"use client";

import * as React from "react";

import { type DropdownMenuProps } from "@radix-ui/react-dropdown-menu";

import { PlaceholderPlugin } from "@platejs/media/react";
import {
  AudioLinesIcon,
  FileUpIcon,
  FilmIcon,
  ImageIcon,
  LinkIcon,
} from "lucide-react";
import { isUrl, KEYS } from "platejs";
import { useEditorRef } from "platejs/react";
import { toast } from "sonner";
import { useFilePicker } from "use-file-picker";

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/plate/ui/alert-dialog";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/plate/ui/dropdown-menu";
import { Input } from "@/components/plate/ui/input";

import {
  ToolbarSplitButton,
  ToolbarSplitButtonPrimary,
  ToolbarSplitButtonSecondary,
} from "./toolbar";

const MEDIA_CONFIG: Record&lt;
  string,
  {
    accept: string[];
    icon: React.ReactNode;
    title: string;
    tooltip: string;
  }
&gt; = {
  [KEYS.audio]: {
    accept: ["audio/*"],
    icon: &lt;AudioLinesIcon className="size-4" /&gt;,
    title: "Insert Audio",
    tooltip: "Audio",
  },
  [KEYS.file]: {
    accept: ["*"],
    icon: &lt;FileUpIcon className="size-4" /&gt;,
    title: "Insert File",
    tooltip: "File",
  },
  [KEYS.img]: {
    accept: ["image/*"],
    icon: &lt;ImageIcon className="size-4" /&gt;,
    title: "Insert Image",
    tooltip: "Image",
  },
  [KEYS.video]: {
    accept: ["video/*"],
    icon: &lt;FilmIcon className="size-4" /&gt;,
    title: "Insert Video",
    tooltip: "Video",
  },
};

export function MediaToolbarButton({
  nodeType,
  ...props
}: DropdownMenuProps & { nodeType: string }) {
  const currentConfig = MEDIA_CONFIG[nodeType];

  const editor = useEditorRef();
  const [open, setOpen] = React.useState(false);
  const [dialogOpen, setDialogOpen] = React.useState(false);

  const { openFilePicker } = useFilePicker({
    accept: currentConfig!.accept,
    multiple: true,
    onFilesSelected: ({ plainFiles: updatedFiles }) =&gt; {
      editor.getTransforms(PlaceholderPlugin).insert.media(updatedFiles);
    },
  });

  return (
    &lt;&gt;
      &lt;ToolbarSplitButton
        onClick={() =&gt; {
          openFilePicker();
        }}
        onKeyDown={(e) =&gt; {
          if (e.key === "ArrowDown") {
            e.preventDefault();
            setOpen(true);
          }
        }}
        pressed={open}
      &gt;
        &lt;ToolbarSplitButtonPrimary&gt;
          {currentConfig!.icon}
        &lt;/ToolbarSplitButtonPrimary&gt;

        &lt;DropdownMenu
          open={open}
          onOpenChange={setOpen}
          modal={false}
          {...props}
        &gt;
          &lt;DropdownMenuTrigger asChild&gt;
            &lt;ToolbarSplitButtonSecondary /&gt;
          &lt;/DropdownMenuTrigger&gt;

          &lt;DropdownMenuContent
            onClick={(e) =&gt; e.stopPropagation()}
            align="start"
            alignOffset={-32}
          &gt;
            &lt;DropdownMenuGroup&gt;
              &lt;DropdownMenuItem onSelect={() =&gt; openFilePicker()}&gt;
                {currentConfig!.icon}
                Upload from computer
              &lt;/DropdownMenuItem&gt;
              &lt;DropdownMenuItem onSelect={() =&gt; setDialogOpen(true)}&gt;
                &lt;LinkIcon /&gt;
                Insert via URL
              &lt;/DropdownMenuItem&gt;
            &lt;/DropdownMenuGroup&gt;
          &lt;/DropdownMenuContent&gt;
        &lt;/DropdownMenu&gt;
      &lt;/ToolbarSplitButton&gt;

      &lt;AlertDialog
        open={dialogOpen}
        onOpenChange={(value) =&gt; {
          setDialogOpen(value);
        }}
      &gt;
        &lt;AlertDialogContent className="gap-6"&gt;
          &lt;MediaUrlDialogContent
            currentConfig={currentConfig!}
            nodeType={nodeType}
            setOpen={setDialogOpen}
          /&gt;
        &lt;/AlertDialogContent&gt;
      &lt;/AlertDialog&gt;
    &lt;/&gt;
  );
}

function MediaUrlDialogContent({
  currentConfig,
  nodeType,
  setOpen,
}: {
  currentConfig: (typeof MEDIA_CONFIG)[string];
  nodeType: string;
  setOpen: (value: boolean) =&gt; void;
}) {
  const editor = useEditorRef();
  const [url, setUrl] = React.useState("");

  const embedMedia = React.useCallback(() =&gt; {
    if (!isUrl(url)) return toast.error("Invalid URL");

    setOpen(false);
    editor.tf.insertNodes({
      children: [{ text: "" }],
      name: nodeType === KEYS.file ? url.split("/").pop() : undefined,
      type: nodeType,
      url,
    });
  }, [url, editor, nodeType, setOpen]);

  return (
    &lt;&gt;
      &lt;AlertDialogHeader&gt;
        &lt;AlertDialogTitle&gt;{currentConfig.title}&lt;/AlertDialogTitle&gt;
      &lt;/AlertDialogHeader&gt;

      &lt;AlertDialogDescription className="group relative w-full"&gt;
        &lt;label
          className="absolute top-1/2 block -translate-y-1/2 cursor-text px-1 text-sm text-muted-foreground/70 transition-all group-focus-within:pointer-events-none group-focus-within:top-0 group-focus-within:cursor-default group-focus-within:text-xs group-focus-within:font-medium group-focus-within:text-foreground has-[+input:not(:placeholder-shown)]:pointer-events-none has-[+input:not(:placeholder-shown)]:top-0 has-[+input:not(:placeholder-shown)]:cursor-default has-[+input:not(:placeholder-shown)]:text-xs has-[+input:not(:placeholder-shown)]:font-medium has-[+input:not(:placeholder-shown)]:text-foreground"
          htmlFor="url"
        &gt;
          <span>URL</span>
        &lt;/label&gt;
        <input> setUrl(e.target.value)}
          onKeyDown={(e) =&gt; {
            if (e.key === "Enter") embedMedia();
          }}
          placeholder=""
          type="url"
          autoFocus
        /&gt;
      &lt;/AlertDialogDescription&gt;

      &lt;AlertDialogFooter&gt;
        &lt;AlertDialogCancel&gt;Cancel&lt;/AlertDialogCancel&gt;
        &lt;AlertDialogAction
          onClick={(e) =&gt; {
            e.preventDefault();
            embedMedia();
          }}
        &gt;
          Accept
        &lt;/AlertDialogAction&gt;
      &lt;/AlertDialogFooter&gt;
    &lt;/&gt;
  );
}
